/*  GMooc - A Java web application for delivering massive open online courses
*   Copyright (C) 2012 Charles A. Wight
*   
*    This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.gmooc;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Id;
import javax.persistence.Transient;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.annotation.Cached;
import com.googlecode.objectify.annotation.Serialized;
import com.googlecode.objectify.annotation.Unindexed;

@Cached
public class Course implements Comparable<Course>,Serializable {
	private static final long serialVersionUID = 137L;
	@Unindexed @Id Long id;
	String title;
	Date start;
	Date end;
	boolean published;
	List<String> instructorIds = new ArrayList<String>();
	List<String> teachingAssistantIds = new ArrayList<String>();
	@Serialized List<Module> modules = new ArrayList<Module>();
	
	@Transient static Objectify ofy = new DAO().ofy();

	Course() {}

	Course(String title, User instructor) {
		this.title = title;
		setInstructor(instructor);
		ofy.put(this);
		for (int i=0; i<6; i++) modules.add(new Module("Week " + i));
	}
	
	long getId() {
		return id;
	}
	
	String getTitle() {
		return title;
	}
	
	void setTitle(String t) {
		title = t;
	}
	
	Date getStart() {
		return start;
	}
	
	String getStartDate() {
		try {
			return SimpleDateFormat.getDateInstance().format(start);
		} catch (Exception e) {
			return "TBA";
		}
	}
	
	void setStart(String startDate) {
		try {
			start = SimpleDateFormat.getDateInstance().parse(startDate);
		} catch (Exception e) {
			start = null;
		}
	}
	
	Date getEnd() {
		return end;
	}
	
	String getEndDate() {
		try {
			return SimpleDateFormat.getDateInstance().format(end);	
		} catch (Exception e) {
			return "TBA";
		}
	}
	
	void setEnd(String endDate) {
		try {
			end = SimpleDateFormat.getDateInstance().parse(endDate);
		} catch (Exception e) {
			start = null;
		}
	}
	
	void setPublished(boolean p) {
		published = p;
	}
	
	boolean getPublished() {
		return published;
	}
	
	User getInstructor() {
		return User.getInstance(instructorIds.get(0));
	}
	
	List<String> getInstructorIds() {
		return instructorIds;
	}
	
	void setInstructor(User u) {
		instructorIds.remove(u.getId());
		instructorIds.add(0,u.getId());
	}
	
	void addInstructor(User u) {
		if (!instructorIds.contains(u.getId())) instructorIds.add(u.getId());
	}
	
	boolean removeInstructor(User u) {
		return instructorIds.remove(u.getId());
	}
	
	boolean isInstructor(User u) {
		return instructorIds.contains(u.getId());
	}
	
	List<String> getTeachingAssistantIds() {
		return teachingAssistantIds;
	}
	
	void addTeachingAssistant(User u) {
		if (!teachingAssistantIds.contains(u.getId())) teachingAssistantIds.add(u.getId());
	}
	
	boolean removeTeachingAssistant(User u) {
		return teachingAssistantIds.remove(u.getId());
	}
	
	boolean isTeachingAssistant(User u) {
		return teachingAssistantIds.contains(u.getId());
	}
	
    public int compareTo(Course other) {
    	try {
    		int start = (int)(this.start.getTime() - other.start.getTime());
    		return start==0? this.title.compareTo(other.title):start;
    	} catch (Exception e) {
    		return this.title.compareTo(other.title); // occurs if difference between start times is greater than MAX_INTEGER
    	}
    }

}